<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html>
<head>
<!--
Not Automatically generated, changed!:
$Id: syntax_control_structures.htm,v 1.2 2008/04/21 20:31:23 wilbertd Exp $ 
-->
<meta http-equiv="Content-Type" content="text/html; charset=iso-8859-1">
<title>Syntax - Control structures</title>
<link rel="stylesheet" type="text/css" href="../avisynth.css">
</head>
<body>
<h2><span class="mw-headline">AviSynth Syntax - Control structures</span></h2>
<p>In the strict sense, <a href="syntax.htm" title="AviSynth Syntax">AviSynth
Syntax</a> provides only one control structure (actually two, the other being
the conditional <a href="syntax_operators.htm" title="Operators">operator</a>,
<tt>?:</tt>, presented elsewhere), the <tt>try..catch</tt> statement.</p>
<script type="text/javascript"> if (window.showTocToggle) { var tocShowText = "show"; var tocHideText = "hide"; showTocToggle(); } </script>
<a name="The_try..catch_statement"></a>
<h2>Contents</h2>
<ul>
  <li class="toclevel-1"><a href="http://avisynth.org/mediawiki/Control_structures#The_try..catch_statement"><span class="tocnumber">1</span>
    <span class="toctext">The try..catch statement</span></a></li>
  <li class="toclevel-1"><a href="http://avisynth.org/mediawiki/Control_structures#Other_control_structures_.28in_the_broad_sense.29"><span class="tocnumber">2</span>
    <span class="toctext">Other control structures (in the broad sense)</span></a>
    <ul>
      <li class="toclevel-2"><a href="http://avisynth.org/mediawiki/Control_structures#Example_1:_Create_a_function_that_returns_a_n-times_repeated_character_sequence"><span class="tocnumber">2.1</span>
        <span class="toctext">Example 1: Create a function that returns a
        n-times repeated character sequence</span></a></li>
      <li class="toclevel-2"><a href="http://avisynth.org/mediawiki/Control_structures#Example_2:_Create_a_function_that_selects_frames_of_a_clip_in_arbitrary_intervals"><span class="tocnumber">2.2</span>
        <span class="toctext">Example 2: Create a function that selects frames
        of a clip in arbitrary intervals</span></a></li>
    </ul>
  </li>
</ul>
<h3><span class="mw-headline">The <tt>try..catch</tt> statement</span></h3>
<p>The <tt>try..catch</tt> statement permits the execution of code that <b>may</b>
generate a run-time error and the handling of the error, if it actually arises.</p>
<p>The full syntax of the <tt>try..catch</tt> statement is:</p>
<pre>try {
    ...
    statements
    ...
}
catch(err_msg) {
    ...
    statements
    ...
}</pre>
<p>The <tt>err_msg</tt> string in the <tt>catch</tt> block contains the text
generated by AviSynth when the error inside the <tt>try</tt> block was
encountered. This text is the same that would appear in the familiar MessageBox
that shows up when a fatal script error occures.</p>
<p>You can query the text (it is a normal string <a href="syntax_script_variables.htm" title="Script variables">variable</a>)
to find specific substrings inside that indicate the error that has been
encountered. This is a technique that can produce many useful results (for an
example, see <a href="http://forum.doom9.org/showthread.php?t=66627" class="external text" title="http://forum.doom9.org/showthread.php?t=66627" rel="nofollow">here</a>).</p>
<a name="Other_control_structures_.28in_the_broad_sense.29"></a>
<h3><span class="mw-headline">Other control structures (in the broad sense)</span></h3>
<p>In the broad sense, there are many elements inside <a href="syntax.htm" title="AviSynth Syntax">AviSynth
Syntax</a> that although not control structures by themselves, together they
allow the creation of language constructs equivalent to a control structure.
Those constructs in turn allow the performance of complex programming tasks.</p>
<p>The elements under consideration are the following:</p>
<ol>
  <li>The <tt>Eval()</tt> statement that allows execution of arbitrary script
    language statements (and its cousin <tt>Apply</tt> that simplifies calling
    functions by name).</li>
  <li>Multiline strings and in particular multiline strings surrounded by triple
    double quotes (the <tt>&quot;&quot;&quot;</tt> sequence of chars), since
    they allow to write string literals inside them naturally, as one would do
    in a normal AviSynth script.</li>
  <li>The <tt>Import()</tt> statement that allows execution of arbitrary
    scripts, which can return a value (not necessarily a clip; a script can
    return a value of any type, which can be assigned to a <a href="syntax_script_variables.htm" title="Script variables">variable</a>
    of the calling script).</li>
  <li>Recursion (the ability to create recursive functions).</li>
  <li>Control functions, in particular Assert, Select, Default, NOP.</li>
</ol>
<p>The first three allow one to create simple <a href="script_ref_block_statements.htm" title="Block statements">Block
statements</a>, such as branching blocks (the analogous of the <tt>if..elseif..else</tt>
control structure commonly encountered in programming and scripting languages).
A basic example is presented below (see the link above for more):</p>
<pre># define different filtering based on this flag
<font color="#FF0000">heavy_filtering = true</font>
<a href="corefilters/avisource.htm" title="AviSource">AviSource</a>(&quot;c:\sources\mysource.avi&quot;)
# assign result of Eval() to a variable to preserve the value of the last special variable
dummy = flag&nbsp;? Eval(&quot;&quot;&quot;
    <a href="corefilters/levels.htm" title="Levels">Levels</a>(0, 1.2, 255, 20, 235)
    stext = &quot;heavily filtered&quot;
    <a href="corefilters/resize.htm" title="Spline36Resize">Spline36Resize</a>(720, 400)
&quot;&quot;&quot;)&nbsp;: Eval(&quot;&quot;&quot;
    stext = &quot;lightly filtered&quot;
    <a href="corefilters/resize.htm" title="BicubicResize">BicubicResize</a>(720, 400)
&quot;&quot;&quot;
<a href="corefilters/addborders.htm" title="AddBorders">AddBorders</a>(0, 40, 0, 40)
<a href="corefilters/subtitle.htm" title="Subtitle">Subtitle</a>(stext)</pre>
<p>The fourth is the general tool provided by the <a href="syntax.htm" title="AviSynth Syntax">syntax</a>
for operating on collections and calculating expressions of any complexity. It
is also, currently, <b>the only</b> tool.</p>
<p>This does not mean that there is something that you can't do inside the
AviSynth script language; in fact recursion together with assignment can achieve
everything an imperative language with looping constructs can do. It just does
it in a way that most people without special programming skills are not
familiar, since functional programming is not a major ICT course but rather a
specialised topic.</p>
<p>The fifth are more or less necessary tools inside the above constructs for
controlling input, setting values and facilitating proper execution of the
construct.</p>
<p>Lets look at some examples of recursion, to grasp the general pattern that
one must follow to master it for its purposes.</p>
<a name="Example_1:_Create_a_function_that_returns_a_n-times_repeated_character_sequence"></a>
<h4><span class="mw-headline">Example 1: Create a function that returns a
n-times repeated character sequence</span></h4>
<p>We will use an existing implementation, from <a href="http://avslib.sourceforge.net/" class="external text" title="http://avslib.sourceforge.net/" rel="nofollow">AVSLib</a>
as our example:</p>
<pre>Function StrFill(string s, int count, bool &quot;strict&quot;) {
    strict = <a href="syntax_internal_functions_control.htm">Default</a>(strict, true)
    <a href="syntax_internal_functions_control.htm">Assert</a>((strict&nbsp;? count &gt;= 0&nbsp;: true), &quot;StrFill: 'count' cannot be negative&quot;)
    return count &gt; 0&nbsp;? s + StrFill(s, count - 1)&nbsp;: &quot;&quot;
}</pre>
<p>The recursion is the call that the function makes to itself at the <tt>return</tt>
statement. In order to be done properly, the sequence of recursive calls must
eventually end to a single return value. Thus a recursive function's return
statement will always use the conditional <a href="syntax_operators.htm" title="Operators">operator</a>,
<tt>?:</tt>.</p>
<p>This is all that is about recursion, the other two lines (where the fifth
element, control functions are used) are simply for ensuring that proper
arguments are passed in. The &quot;strict&quot; argument is just and add-on for
using the functions in case where it should quietly (without throwing an error)
return an empty string.</p>
<a name="Example_2:_Create_a_function_that_selects_frames_of_a_clip_in_arbitrary_intervals"></a>
<h4><span class="mw-headline">Example 2: Create a function that selects frames
of a clip in arbitrary intervals</span></h4>
<p>Filters like <a href="corefilters/selectevery.htm" title="SelectEvery">SelectEvery</a>
allow the efficient selection of arbitrary sets of frames. They require though
that each set of frames has a constant frame separation with its successor and
predecessor set (in other words, the sets are periodic on frame number). In
order to select frames with varying separation (that is non-periodic) we have to
resort to script functions that use recursion.</p>
<p>The function below is a generic frame selection filter, which in order to
select arbitrary frames uses a user-defined function (the <tt>func</tt> argument
must contain its name) that maps the interval <tt>[s_idx..e_idx)</tt> to the set
of frames that will be selected. <tt>func</tt> must accept a single integer as
argument and return the corresponding mapped frame number.</p>
<pre>Function FSelectEvery(clip c, string func, int s_idx, int e_idx) {
    <a href="syntax_internal_functions_control.htm">Assert</a>(s_idx &gt;= 0, &quot;FSelectEvery: start frame index (s_idx) is negative&quot;)
    f = <a href="syntax_internal_functions_control.htm">Apply</a>(func, s_idx)
    return (s_idx &lt; e_idx &amp;&amp; f &gt;= 0 &amp;&amp; f &lt; c.Framecount) \
      &nbsp;? c.<a href="corefilters/trim.htm" title="Trim">Trim</a>(f, -1) + FSelectEvery(c, func, s_idx + 1, e_idx) \
      &nbsp;: c.<a href="corefilters/blankclip.htm">BlankClip</a>(length=0)
}</pre>
<p>The recursive step (first conditional branch in the <tt>return</tt>
statement) is again an expression that involves the function as a subpart. This
is not necessary in the general case (depending on the specific task, it could
also be just the function call) but it is the most usual case when building
complex constructs.</p>
<p><tt>Apply</tt> calls the user function to calculate the frame number (a more
robust implementation would enclose this call in a <tt>try...catch</tt> block).
If the frame number is within the clip's frames then the associated frame is
appended to the result else recursion ends.</p>
<p>The following example will clarify the design:</p>
<pre># my custom selector (x^2)
Function CalcFrame(int idx) { return Int(Pow(idx, 2)) }

<a href="corefilters/avisource.htm" title="AviSource">AviSource</a>(&quot;my_200_frames.avi&quot;)
# select up to 20 frames, mapped by CalcFrame
# in this case: 0, 1, 4, 9, 16, 25, 36, 49, 64, 81, 100, 121, 144, 169, 196
FSelectEvery(last, &quot;CalcFrame&quot;, 0, 20)</pre>
<p><kbd>$Date: 2008/04/21 20:31:23 $</kbd></p>
</body>
</html>
